package com.cenxi.manage;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.cenxi.common.constants.Constants;
import com.cenxi.common.convert.AccountDTOTOAccountEntity;
import com.cenxi.common.convert.MenuDTOToMenuEntity;
import com.cenxi.common.dto.req.MenuReqDTO;
import com.cenxi.common.dto.resp.MenuRespDTO;
import com.cenxi.common.util.JwtUtils;
import com.cenxi.common.util.MenuUtils;
import com.cenxi.common.util.SecurityUtils;
import com.cenxi.common.util.req.PageReq;
import com.cenxi.common.util.req.Req;
import com.cenxi.common.util.resp.PageResp;
import com.cenxi.common.util.resp.Resp;
import com.cenxi.dao.domain.AccountRole;
import com.cenxi.dao.domain.Menu;
import com.cenxi.dao.domain.RoleMenu;
import com.cenxi.dao.mapper.AccountRoleMapper;
import com.cenxi.dao.mapper.MenuMapper;
import com.cenxi.dao.mapper.RoleMenuMapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @Author cenxi
 * @Date 2023/8/16 11:48
 * @Version 1.0
 */
@Slf4j
@Component
public class ManageMenuService {

    @Autowired
    private MenuMapper menuMapper;
    @Autowired
    private AccountRoleMapper accountRoleMapper;
    @Autowired
    private RoleMenuMapper  roleMenuMapper;
    public PageResp<MenuRespDTO> page(PageReq<MenuReqDTO> req) {
        MenuReqDTO data = req.getData();
        LambdaQueryWrapper<Menu> lqw = new LambdaQueryWrapper<>();
        lqw.eq(Menu::getDeleted, Constants.ENABLE)
                .eq(Objects.nonNull(data.getState()), Menu::getState, data.getState())
                .like(StringUtils.isNotBlank(data.getMenuName()), Menu::getMenuName, data.getMenuName())
                .orderByDesc(Menu::getCreateTime);
        Page<Menu> menuPage = menuMapper.selectPage(new Page<>(req.getPageIndex(), req.getPageSize()), lqw);
        return PageResp.succeed(menuPage.getPages(), menuPage.getTotal(),
                menuPage.hasNext(), MenuUtils.treeMenu(menuPage.getRecords()));
    }

    public Resp<Boolean> create(Req<MenuReqDTO> req) {
        Menu menu = MenuDTOToMenuEntity.INTERFACE.menuReqToMenu(req.getData());
        return Resp.succeed(menuMapper.insert(menu) > 0);
    }

    public Resp<MenuRespDTO> findById(String data) {
        return Resp.succeed(MenuDTOToMenuEntity.INTERFACE.entity2dto(menuMapper.selectById(data)));
    }

    public Resp<Boolean> edit(Req<MenuReqDTO> req) {
        return Resp.succeed(menuMapper.updateById(MenuDTOToMenuEntity.INTERFACE.menuReqToMenu(req.getData())) > 0);
    }

    public Resp<Boolean> enable(String data, byte enable) {
        Menu menu = menuMapper.selectById(data);
        if (Objects.isNull(menu)) {
            return Resp.error("路由菜单不存在");
        }
        Menu mu = new Menu();
        mu.setId(menu.getId());
        mu.setState((int) enable);
        return Resp.succeed(menuMapper.updateById(mu) > 0);
    }

    public Resp<Boolean> disable(String data, byte disable) {
        Menu menu = menuMapper.selectById(data);
        if (Objects.isNull(menu)) {
            return Resp.error("路由菜单不存在");
        }
        Menu mu = new Menu();
        mu.setId(menu.getId());
        mu.setState((int) disable);
        return Resp.succeed(menuMapper.updateById(mu) > 0);
    }

    public Resp<Boolean> deleteById(String data) {
        // 检查是否存在子菜单
        LambdaQueryWrapper<Menu> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Menu::getParentId, data);
        if (menuMapper.exists(wrapper)) {
            return Resp.error("存在子菜单，不允许删除");
        }
        return Resp.succeed(menuMapper.deleteById(data) > 0);
    }

    public Resp<List<MenuRespDTO>> selectTree() {
        List<Menu> menus = menuMapper.selectList(new LambdaQueryWrapper<Menu>()
                .eq(Menu::getDeleted, Constants.ENABLE)
                .eq(Menu::getState, Constants.ENABLE));
        return Resp.succeed(MenuUtils.treeMenu(menus));
    }

    public Resp<List<MenuRespDTO>> getRouters() {
        String userId = JwtUtils.getUserId(SecurityUtils.getToken());
        if (StringUtils.isBlank(userId)) {
            return Resp.error("登录账户信息不存在，请重新登录");
        }
        // 通过用户id 查询所属路由
        List<Long> collect = accountRoleMapper.selectList(new LambdaQueryWrapper<AccountRole>()
                .eq(AccountRole::getAccountId, userId)).stream().map(AccountRole::getRoleId).collect(Collectors.toList());
        if (CollectionUtils.isEmpty(collect)) {
            return Resp.succeed(MenuUtils.treeMenu(null));
        }
//        List<Menu> menus = menuMapper.selectRoutByUserId(userId);
        return Resp.succeed(MenuUtils.treeMenu(menuMapper.selectBatchIds(roleMenuMapper.selectList(new LambdaQueryWrapper<RoleMenu>()
                        .in(RoleMenu::getRoleId, collect))
                .stream().map(RoleMenu::getMenuId)
                .collect(Collectors.toList()))));
    }
}
